package com.yjz.common.restful

import com.google.gson.Gson
import com.yjz.common.cache.RoomStorageCache
import com.yjz.common.restful.annotation.CacheStrategy
import com.yjz.common.thread.YThreadPool
import com.yjz.common.util.MainHandler
import com.yjz.log.JLog

/**
 *作用 : Call创建，请求发起拦截分发
 *作者 : yjz
 *时间 : 2025/2/11 14:02
 */
class Scheduler(private val factory: JCall.Factory, private val interceptors: MutableList<Interceptor>) {

    fun newCall(requestInfo: RequestInfo): JCall<*> {
        val newCall = factory.newCall(requestInfo)
        return ProxyJCall(newCall, requestInfo)
    }

    internal inner class ProxyJCall<T>(private val delegate: JCall<T>, private val requestInfo: RequestInfo) : JCall<T> {
        // 同步方法执行
        override fun execute(): HttpBaseResponse<T> {
            // 请求之前的拦截器
            dispatchInterceptor(requestInfo, null)
            if (requestInfo.cacheStrategy == CacheStrategy.CACHE_FIRST) {
                val cacheResponse = readCache<T>()
                if (cacheResponse.data != null) {
                    return cacheResponse
                }
            }
            val response = delegate.execute()
            saveCacheIfNeed(response)
            // 请求之后的拦截器
            dispatchInterceptor(requestInfo, response)
            return response
        }

        // 异步方法执行
        override fun enqueue(callback: CallBack<T>) {
            dispatchInterceptor(requestInfo, null)

            if (requestInfo.cacheStrategy == CacheStrategy.CACHE_FIRST) {
                YThreadPool.getInstance().execute {
                    val cacheResponse = readCache<T>()
                    if (cacheResponse.data != null) {
                        MainHandler.sendAtFrontOfQueue {
                            callback.onSuccess(cacheResponse)/*自线程,handler切主线程*/
                        }
                    }
                }
            }

            delegate.enqueue(object : CallBack<T> {
                override fun onSuccess(response: HttpBaseResponse<T>) {
                    dispatchInterceptor(requestInfo, response)
                    saveCacheIfNeed(response)
                    callback.onSuccess(response)
                }

                override fun onFailed(throwable: Throwable) {
                    callback.onFailed(throwable)
                }
            })
        }

        private fun dispatchInterceptor(request: RequestInfo, response: HttpBaseResponse<T>?) {
            if (interceptors.size <= 0)
                return
            InterceptorChain(request, response).dispatch()
        }

        internal inner class InterceptorChain<T>(private val request: RequestInfo, private val response: HttpBaseResponse<T>?) : Interceptor.Chain {

            //代表的是 分发的第几个拦截器
            private var callIndex: Int = 0

            override val isRequestPeriod: Boolean
                get() = response == null

            fun dispatch() {
                val interceptor = interceptors[callIndex]
                val intercept = interceptor.intercept(this)
                callIndex++
                if (!intercept && callIndex < interceptors.size) {
                    dispatch()
                }
            }

            override fun request() = request

            override fun response() = response
        }

        /**
         * 缓存请求结果
         */
        private fun saveCacheIfNeed(response: HttpBaseResponse<T>) {
            if (requestInfo.cacheStrategy == CacheStrategy.CACHE_FIRST || requestInfo.cacheStrategy == CacheStrategy.NET_CACHE) {
                if (response.data != null) {
                    YThreadPool.getInstance().execute {
                        RoomStorageCache.saveCache(requestInfo.getCacheKey(), response.data)
                    }
                }
            }
        }

        private fun <T> readCache(): HttpBaseResponse<T> {
            // key的审查
            val cache = RoomStorageCache.getCache<T>(requestInfo.getCacheKey())
            val cacheResponse = HttpBaseResponse<T>()
            cacheResponse.data = cache
            cacheResponse.code = HttpBaseResponse.SUCCESS_BY_CACHE
            cacheResponse.msg = "缓存获取成功"
            return cacheResponse
        }
    }
}

